package com.mlx.mbg.code.method;

import com.mlx.mbg.code.MbgUtil;
import com.mlx.mbg.code.inter.EnableMethod;
import com.mlx.mbg.code.config.MbgPropertyConfig;
import com.mlx.mbg.code.inter.ExtensionLevel;
import com.mlx.mbg.code.inter.IExtensionMethod;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@EnableMethod
public class ListQueryMethod implements IExtensionMethod {
    @Override
    public boolean checkConfig(ExtensionLevel level, MbgPropertyConfig mbgPropertyConfig, IntrospectedTable introspectedTable) {
        return getExtensionLevelSet().contains(level) && mbgPropertyConfig.getEnableListQuery() && MbgUtil.checkSelectListQueryExpressionFormat(introspectedTable, "列表查询", "selectListQuery");
    }

    @Override
    public int getOrder() {
        return 1600;
    }

    @Override
    public List<Method> buildMethod(IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();
        String selectListQueryString = introspectedTable.getTableConfigurationProperty("selectListQuery");

        List<IntrospectedColumn> columnList = new ArrayList<>();
        if (MbgUtil.isNotEmpty(selectListQueryString)){
            String[] selectListQueryColumns = selectListQueryString.split(",");
            for (String selectListQueryColumn : selectListQueryColumns){
                IntrospectedColumn column = introspectedTable.getColumn(selectListQueryColumn);
                columnList.add(column);
            }
        }

        FullyQualifiedJavaType modelType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());


        List<Parameter> methodParameterList = new ArrayList<Parameter>();
        for (IntrospectedColumn column : columnList){
            String javaProperty = column.getJavaProperty();
            FullyQualifiedJavaType javaType = column.getFullyQualifiedJavaType();
            // 参数类型
            FullyQualifiedJavaType methodParameterType = new FullyQualifiedJavaType(javaType.getShortName());
            // 方法参数
            Parameter methodParameter = new Parameter(methodParameterType, javaProperty);
            methodParameterList.add(methodParameter);

        }

        // 访问类型：public
        JavaVisibility methodVisibility = JavaVisibility.PUBLIC;

        // 返回类型：List
        FullyQualifiedJavaType returnType = new FullyQualifiedJavaType("List");
        // 设置泛型参数
        returnType.addTypeArgument(modelType);

        // 方法名称
        String methodName = "listQuery";

        // 创建方法对象
        Method method = new Method();
        // 设置访问类型
        method.setVisibility(methodVisibility);
        // 设置返回类型对象
        method.setReturnType(returnType);
        // 设置方法名
        method.setName(methodName);
        // 设置参数
        for (Parameter parameter : methodParameterList){
            method.addParameter(parameter);
        }

        // 设置备注
        method.addJavaDocLine("/**");
        method.addJavaDocLine(" * 列表查询");
        method.addJavaDocLine(" */");

        return Collections.singletonList(method);
    }

    @Override
    public List<XmlElement> buildSQL(IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();
        String selectListQueryString = introspectedTable.getTableConfigurationProperty("selectListQuery");

        List<IntrospectedColumn> columnList = new ArrayList<>();

        if (MbgUtil.isNotEmpty(selectListQueryString)){
            String[] selectListQueryColumns = selectListQueryString.split(",");
            for (String selectListQueryColumn : selectListQueryColumns){
                IntrospectedColumn column = introspectedTable.getColumn(selectListQueryColumn);
                columnList.add(column);
            }
        }

        XmlElement where = new XmlElement("where");

        for (IntrospectedColumn column : columnList){
            String actualColumnName = column.getActualColumnName();
            String javaProperty = column.getJavaProperty();
            FullyQualifiedJavaType javaType = column.getFullyQualifiedJavaType();
            String jdbcTypeName = column.getJdbcTypeName();

            XmlElement whereIf = new XmlElement("if"); //$NON-NLS-1$
            String ifTest = javaProperty + " != null";
            if ("String".equals(javaType.getShortName())){
                ifTest = ifTest + " and " + javaProperty + " != ''";
            }
            whereIf.addAttribute(new Attribute("test",  ifTest));
            whereIf.addElement(new TextElement("and " + actualColumnName + " = #{" + javaProperty + ",jdbcType=" + jdbcTypeName + "}"));
            where.addElement(whereIf);
        }

        XmlElement listQuery = new XmlElement("select");
        listQuery.addAttribute(new Attribute("id", "listQuery"));
        listQuery.addAttribute(new Attribute("resultMap", "BaseResultMap"));
        TextElement text3 = new TextElement("select");
        XmlElement baseInclude = new XmlElement("include");
        baseInclude.addAttribute(new Attribute("refid", "Base_Column_List"));
        TextElement text4 = new TextElement("from " + introspectedTable.getFullyQualifiedTableNameAtRuntime());
        listQuery.addElement(text3);
        listQuery.addElement(baseInclude);
        listQuery.addElement(text4);

        if (!columnList.isEmpty()){
            listQuery.addElement(where);
        }

        return Collections.singletonList(listQuery);
    }
}
